//
//  AKEntry.m
//  CocoaBean
//
//  Created by sleeper on 5/18/10.
//  Copyright 2010 __MyCompany__ All rights reserved.
//

#import "NSDate_DoubanAddition.h"
#import "NSDictionary_DoubanAddition.h"

#import "AKEntry_Private.h"

NSString * const kAKEntryKeyDoubanAttribute = @"db:attribute";
NSString * const kAKEntryKeyAuthor = @"author";
NSString * const kAKEntryKeyLink = @"link";
NSString * const kAKEntryKeyName = @"name";
NSString * const kAKEntryKeyURI = @"uri";
NSString * const kAKEntryKeyCategory = @"category";
NSString * const kAKEntryKeyContent = @"content";
NSString * const kAKEntryKeyId = @"id";
NSString * const kAKEntryKeyPublished = @"published";
NSString * const kAKEntryKeyTitle = @"title";
NSString * const kAKEntryKeyDoubanTag = @"db:tag";
NSString * const kAKEntryKeyGDRating = @"gd:rating";
NSString * const kAKEntryKeySummary = @"summary";

// Starts with @
NSString * const kAKEntrySubkeyHref = @"@href";
NSString * const kAKEntrySubkeyRel = @"@rel";
NSString * const kAKEntrySubkeyName = @"@name";
NSString * const kAKEntrySubkeyScheme = @"@scheme";
NSString * const kAKEntrySubkeyTerm = @"@term";
NSString * const kAKEntrySubkeyType = @"@type";
NSString * const kAKEntrySubkeyCount = @"@count";
NSString * const kAKEntrySubkeyAverage = @"@average";
NSString * const kAKEntrySubkeyMax = @"@max";
NSString * const kAKEntrySubkeyMin = @"@min";
NSString * const kAKEntrySubkeyNumRaters = @"@numRaters";

NSString * const _kAKEntryEncodeKeyDict = @"akDict";

@implementation AKEntry

@synthesize dictionary = _dictionary, entryIdURL = _entryIdURL, entryId = _entryId;

+ (NSArray*)entriesWithDictionaries:(NSArray*)dictionaries
{
	NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:[dictionaries count]];
	for (NSDictionary *dict in dictionaries) {
		AKEntry *entry = [[[self class] alloc] initWithDictionary:dict];
		[array addObject:entry];
		[entry release];
	}
	NSArray *retVal = [[array copy] autorelease];
	[array release];
	return retVal;
}

- (id)initWithDictionary:(NSDictionary*)dictionary
{
	if ((self = [super init])) {
		_dictionary = [dictionary copy];
	}
	return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
	if ((self = [super init])) {
		_dictionary = [[aDecoder decodeObjectForKey:_kAKEntryEncodeKeyDict] copy];
//		_publishDate = [[aDecoder decodeObjectForKey:_kAKEntryEncodeKeyDate] copy];
	}
	return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
	[aCoder encodeObject:self.dictionary forKey:_kAKEntryEncodeKeyDict];
//	[aCoder encodeObject:self.publishDate forKey:_kAKEntryEncodeKeyDate];
}

- (void)dealloc
{
	AK_RELEASE(_dictionary);
	AK_RELEASE(_entryIdURL);
	AK_RELEASE(_entryId);
	
	AK_RELEASE(_title);
	AK_RELEASE(_relatedURL);
	AK_RELEASE(_imageURL);
	AK_RELEASE(_alternateURL);
	AK_RELEASE(_selfURL);
	AK_RELEASE(_tagNames);
	AK_RELEASE(_tagCounts);
	
	AK_RELEASE(_authors);
	
	[super dealloc];
}

#pragma mark Comparation

- (BOOL)isEqual:(AKEntry *)anotherEntry
{
	return (self == anotherEntry || 
//			([self.publishDate isEqualToDate:anotherEntry.publishDate] && 
			 [self.entryIdURL isEqualToString:anotherEntry.entryIdURL]);
}

#pragma mark Properties

- (NSString *)entryIdURL
{
	if (_entryIdURL == nil)
		_entryIdURL = [[_dictionary akPropertyForKey:kAKEntryKeyId valueKey:nil] copy];
	return _entryIdURL;
}

- (NSString *)entryId
{
	if (_entryId == nil)
		_entryId = [[[self.entryIdURL componentsSeparatedByString:@"/"] lastObject] copy];
	return _entryId;
}

- (NSString*)categoryString
{
	return [[[self.dictionary akPropertyForKey:kAKEntryKeyCategory valueKey:kAKEntrySubkeyTerm] componentsSeparatedByString:@"#"] lastObject];
}

- (AKEntryCategory)category
{
	if (_type == AKEntryCategoryUndefined) {
		NSString *category = [self categoryString];
		if ([category length] > 0) {
			if ([category hasSuffix:@"saying"]) {
				_type = AKEntryCategorySaying;
			}
			else if ([category hasSuffix:@"book"]) {
				_type = AKEntryCategoryBook;
			}
			else if ([category hasSuffix:@"magazine"]) {
				_type = AKEntryCategoryMagazine;
			}
			else if ([category hasSuffix:@"movie"]) {
				_type = AKEntryCategoryMovie;
			}
			else if ([category hasSuffix:@"tv"]) {
				_type = AKEntryCategoryTv;
			}
			else if ([category hasSuffix:@"music"]) {
				_type = AKEntryCategoryMusic;
			}
			else if ([category hasSuffix:@"place"]) {
				_type = AKEntryCategoryPlace;
			}
			else if ([category hasSuffix:@"group"]) {
				_type = AKEntryCategoryGroup;
			}
			else if ([category hasSuffix:@"event"]) {
				_type = AKEntryCategoryEvent;
			}
			else if ([category hasSuffix:@"site"]) {
				_type = AKEntryCategorySite;
			}
			else if ([category hasSuffix:@"recommendation"]) {
				_type = AKEntryCategoryRecommendation;
			}
			else if ([category hasSuffix:@"note"]) {
				_type = AKEntryCategoryNote;
			}
			else if ([category hasSuffix:@"blog"]) {
				_type = AKEntryCategoryBlog;
			}
			else if ([category hasSuffix:@"photo"]) {
				_type = AKEntryCategoryPhoto;
			}
			else if ([category hasSuffix:@"contact"]) {
				_type = AKEntryCategoryContact;
			}
			else if ([category hasSuffix:@"plaza"]) {
				_type = AKEntryCategoryPlaza;
			}
			else if ([category hasSuffix:@"signature"]) {
				_type = AKEntryCategorySignature;
			}
		}
		
		if (_type == AKEntryCategoryUndefined)
			_type = AKEntryCategoryUnkown;
	}
	return _type;
}

@end

@implementation AKEntry (Title)

- (NSString*)title
{
	if (_title == nil) {
		_title = [[self.dictionary akPropertyForKey:kAKEntryKeyTitle valueKey:nil] copy];
	}
	return _title;
}

@end

@implementation AKEntry (Link)

- (NSString *)relatedURL
{
	if (_relatedURL == nil)
		_relatedURL = [[_dictionary akPropertyInArrayForKey:kAKEntryKeyLink subkey:kAKEntrySubkeyRel valueKey:kAKEntrySubkeyHref value:@"related"] copy];
	return _relatedURL;
}

- (NSString *)imageURL
{
	if (_imageURL == nil)
		_imageURL = [[_dictionary akPropertyInArrayForKey:kAKEntryKeyLink subkey:kAKEntrySubkeyRel valueKey:kAKEntrySubkeyHref value:@"image"] copy];
	return _imageURL;
}

- (NSString *)selfURL
{
	if (_selfURL == nil)
		_selfURL = [[_dictionary akPropertyInArrayForKey:kAKEntryKeyLink subkey:kAKEntrySubkeyRel valueKey:kAKEntrySubkeyHref value:@"self"] copy];
	return _selfURL;	
}

- (NSString *)alternateURL
{
	if (_alternateURL == nil)
		_alternateURL = [[_dictionary akPropertyInArrayForKey:kAKEntryKeyLink subkey:kAKEntrySubkeyRel valueKey:kAKEntrySubkeyHref value:@"alternate"] copy];
	return _alternateURL;
}

@end

@implementation AKEntry (Tags)

- (void)_getTags
{
	[_dictionary akGetPropertyArraysForKey:kAKEntryKeyDoubanTag 
								firstArray:&_tagNames firstSubkey:kAKEntrySubkeyName 
							   secondArray:&_tagCounts secondSubkey:kAKEntrySubkeyCount];
	_checkedTags = YES;
}

- (NSUInteger)numberOfTagNames
{
	if (!_checkedTags)
		[self _getTags];
	
	return [_tagNames count];
}

- (NSString *)tagNameAtIndex:(NSUInteger)index
{
	if (!_checkedTags)
		[self _getTags];
	
	return [_tagNames objectAtIndex:index];
}

- (NSInteger)numberOfTagsAtIndex:(NSUInteger)index
{
	NSUInteger retVal = 0;
	if (!_checkedTags)
		[self _getTags];
	
	if (_tagCounts)
		retVal = [[_tagCounts objectAtIndex:index] integerValue];
	
	return retVal;
}

@end

@implementation AKEntry (Rating)

- (float)ratingAverage
{
	return [[_dictionary akPropertyForKey:kAKEntryKeyGDRating valueKey:kAKEntrySubkeyAverage] floatValue];
}

- (float)ratingMax
{
	return [[_dictionary akPropertyForKey:kAKEntryKeyGDRating valueKey:kAKEntrySubkeyMax] floatValue];
}

- (float)ratingMin
{
	return [[_dictionary akPropertyForKey:kAKEntryKeyGDRating valueKey:kAKEntrySubkeyMin] floatValue];
}

- (NSInteger)numberOfRaters
{
	return [[_dictionary akPropertyForKey:kAKEntryKeyGDRating valueKey:kAKEntrySubkeyNumRaters] integerValue];
}

@end

@implementation AKEntry (Authors)

- (NSArray *)authors
{
	if (_authors == nil) {
		NSArray *authorNames = nil;
		[_dictionary akGetPropertyArraysForKey:kAKEntryKeyAuthor firstArray:&authorNames firstSubkey:kAKEntryKeyName secondArray:NULL secondSubkey:nil];
		_authors = [[authorNames valueForKey:kAKEntryKeySingleProperty] copy];
	}
	
	return _authors;
}

@end